﻿#region License Info
//Component of Cronos Package, http://www.codeplex.com/cronos
//Copyright (C) 2009 Anthony Brockwell

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#endregion


using System;
using System.Windows.Forms;
using ABMath.ModelFramework.Data;
using ABMath.ModelFramework.Visuals;
using MathNet.Numerics.LinearAlgebra;

namespace ExtraControlLibrary.VisualControls
{
    [Serializable]
    public partial class CrossCorrelationControl : UserControl, IUpdateable
    {
        private int index0 = 0;
        private int index1 = 1;

        private CrossCorrelationVisual ccv;

        public CrossCorrelationControl()
        {
            InitializeComponent();
        }

        public CrossCorrelationControl(CrossCorrelationVisual ccv)
        {
            InitializeComponent();
            this.ccv = ccv;
            ccv.AssociatedControl = this;
            DataHasChanged();
        }
 
        private void UpdateIndices()
        {
            if (ccv == null)
                return;

            index0 = hScrollBar1.Value;
            index1 = vScrollBar1.Value >= index0 ? vScrollBar1.Value+1 : vScrollBar1.Value;
            var TheTS = ccv.TheObject;
            var mvts = TheTS as MVTimeSeries;
            if (mvts != null)
                ReplotAll();
        }

        private void UpdateScrollBars()
        {
            if (ccv == null)
                return;

            var TheTS = ccv.TheObject;
            var mvts = TheTS as MVTimeSeries;
            if (mvts.Dimension < 2)
                return;  // doesn't make sense for univariate TS

            vScrollBar1.Minimum = 0;
            vScrollBar1.SmallChange = 1;
            vScrollBar1.LargeChange = 1;
            vScrollBar1.Value = 0;
            vScrollBar1.Maximum = mvts.Dimension - 2;

            hScrollBar1.Minimum = 0;
            hScrollBar1.SmallChange = 1;
            hScrollBar1.LargeChange = 1;
            hScrollBar1.Value = 0;
            hScrollBar1.Maximum = mvts.Dimension - 2;
        }

        private void ReplotAll()
        {
            if (ccv == null)
                return;

            int nobs = ccv.TSCount;
            int maxLag = ccv.ACF.Length - 1;
            var acf = ccv.ACF;

            var lags = new int[maxLag+1];
            var cs = new Vector(maxLag+1);
            for (int i=0 ; i<=maxLag ; ++i)
            {
                lags[i] = i;
                cs[i] = acf[i][index0, index0];
            }
            acfPlotBox11.SetACF(lags, cs, nobs);
            acfPlotBox11.Title = ccv.SubTitle(index0) + " ACF";

            lags = new int[maxLag + 1];
            cs = new Vector(maxLag + 1);
            for (int i = 0; i <= maxLag; ++i)
            {
                lags[i] = i;
                cs[i] = acf[i][index1, index1];
            }
            acfPlotBox22.SetACF(lags, cs, nobs);
            acfPlotBox22.Title = ccv.SubTitle(index1) + " ACF";


            lags = new int[maxLag + 1];
            cs = new Vector(maxLag + 1);
            for (int i = 0; i <= maxLag; ++i)
            {
                lags[i] = i;
                cs[i] = acf[i][index0, index1];
            }
            acfPlotBox12.SetACF(lags, cs, nobs);
            acfPlotBox12.Title = "(" + ccv.SubTitle(index0) + ") \u2190 (" + ccv.SubTitle(index1) + ")";


            lags = new int[maxLag + 1];
            cs = new Vector(maxLag + 1);
            for (int i = -maxLag ; i <= 0; ++i)
            {
                lags[i+maxLag] = i;
                cs[i+maxLag] = acf[-i][index1, index0];
            }
            acfPlotBox21.SetACF(lags, cs, nobs);
            acfPlotBox21.Title = "(" + ccv.SubTitle(index0) + ") \u2192 (" + ccv.SubTitle(index1) + ")";
        }

        private void vScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            UpdateIndices();
        }

        private void hScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            UpdateIndices();
        }

        public void DataHasChanged()
        {
            if (ccv == null)
                return;

            // now we can recompute, etc.
            var TheTS = ccv.TheObject;
            var mvts = TheTS as MVTimeSeries;
            if (mvts == null)
                return;
            if (mvts.Dimension < 2)
                return;  // doesn't make sense for univariate TS

            acfPlotBox11.ShowLag0 = true;
            acfPlotBox12.ShowLag0 = true;
            acfPlotBox21.ShowLag0 = true;
            acfPlotBox22.ShowLag0 = true;

            UpdateScrollBars();
            ReplotAll();
        }
    }
}